using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;


namespace lang_benchmarks
{

    public interface ttt
    {
        int a
        {
            get;
            set;
        }
    }
    class Typ : ttt
    {
        int aa = 0;
        public int a
        {
            get { return aa; }
            set { aa = value; }
        }
    }

    class Typ2 : ttt
    {
        int aa = 0;
        int ttt.a
        {
            get { return aa; }
            set { aa = value; }
        }
    }

    class gen1<T>
    {
        public static int get(T b)
        {
            return ((ttt)b).a;
        }
    }

    class gen2<T> where T : ttt
    {
        public static int get(T b)
        {
            return b.a;
        }
    }

    class nongen
    {
        public static int get(ttt b)
        {
            return b.a;
        }
    }

    class nongenobj
    {
        public static int get(object b)
        {
            return ((ttt)b).a;
        }
    }

    [TestFixture]
    public class Generics
    {
        [Test]
        public void GenericsTest()
        {
            Timer T = new Timer();
            int tmp=0;
            Typ B = new Typ();
            ttt A = B;
            int n = 10000000;

            T.Start();
            for (int i = 0; i < n; i++)tmp+=gen1<ttt>.get(A);
            T.Stop();
            Console.WriteLine("gen1 :" + T.Duration);

            
            T.Start();
            for (int i = 0; i < n; i++) tmp += gen2<ttt>.get(A);
            T.Stop();
            Console.WriteLine("gen2 :" + T.Duration);

            T.Start();
            for (int i = 0; i < n; i++)tmp+=gen1<Typ>.get(B);
            T.Stop();
            Console.WriteLine("dgen1 :" + T.Duration);

            
            T.Start();
            for (int i = 0; i < n; i++) tmp += gen2<Typ>.get(B);
            T.Stop();
            Console.WriteLine("dgen2 :" + T.Duration);

            
            T.Start();
            for (int i = 0; i < n; i++) tmp += nongen.get(A);
            T.Stop();
            Console.WriteLine("nongen :" + T.Duration);

            T.Start();
            for (int i = 0; i < n; i++) tmp += nongen.get(B);
            T.Stop();
            Console.WriteLine("nongen2 :" + T.Duration);

            T.Start();
            for (int i = 0; i < n; i++) tmp += nongenobj.get(A);
            T.Stop();
            Console.WriteLine("Object :" + T.Duration);

            Typ P =  new Typ();
            T.Start();
            for (int i = 0; i < n; i++) tmp += P.a;
            T.Stop();
            Console.WriteLine("NoInterface :" + T.Duration);
        }

        [Test]
        public void GenericsTest2()
        {
            Timer T = new Timer();
            int tmp = 0;
            Typ2 B = new Typ2();
            ttt A = B;
            int n = 10000000;

            T.Start();
            for (int i = 0; i < n; i++) tmp += gen1<ttt>.get(A);
            T.Stop();
            Console.WriteLine("gen1 :" + T.Duration);


            T.Start();
            for (int i = 0; i < n; i++) tmp += gen2<ttt>.get(A);
            T.Stop();
            Console.WriteLine("gen2 :" + T.Duration);

            T.Start();
            for (int i = 0; i < n; i++) tmp += gen1<Typ2>.get(B);
            T.Stop();
            Console.WriteLine("dgen1 :" + T.Duration);


            T.Start();
            for (int i = 0; i < n; i++) tmp += gen2<Typ2>.get(B);
            T.Stop();
            Console.WriteLine("dgen2 :" + T.Duration);


            T.Start();
            for (int i = 0; i < n; i++) tmp += nongen.get(A);
            T.Stop();
            Console.WriteLine("nongen :" + T.Duration);

            T.Start();
            for (int i = 0; i < n; i++) tmp += nongenobj.get(A);
            T.Stop();
            Console.WriteLine("Object :" + T.Duration);

            Typ P = new Typ();
            T.Start();
            for (int i = 0; i < n; i++) tmp += P.a;
            T.Stop();
            Console.WriteLine("NoInterface :" + T.Duration);
        }
    }
}

